#!/usr/bin/python
# vim: set fileencoding=utf-8 :
# Copyright (C) 2007 Kévin Dunglas <dunglas@gmail.com>
#
# Authors:
#  Kévin Dunglas
#
# This program is a part of a the Google Summer Of Code 2007
# For futher information see :
# http://code.google.com/soc/ubuntu/appinfo.html?csaid=EF4FCF874D88234
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA

import os
import sys
from optparse import OptionParser
import getpass
import gettext
import locale
import conceal
import __builtin__
__builtin__._ = gettext.gettext

APPNAME="conceal"
APPVERSION="0.0.5"
CACHE = os.environ['HOME'] + "/.conceal/cache"


class Main():
    """Main class"""
    def __init__(self):
    
        self.data = conceal.Data()
        self.folders = self.data.folders
        self.folders.clean()
    
        parser = OptionParser(version="%prog " + APPVERSION)
        parser.add_option("-e", "--encrypt", dest="crypt",\
            help="encrypt FOLDER", metavar="FOLDER")
        parser.add_option("-c", "--close", dest="close",\
            help="close FOLDER", metavar="FOLDER")
        parser.add_option("-o", "--open", dest="_open",\
            help="open encrypted FOLDER", metavar="FOLDER")
        parser.add_option("-i", "--idle", dest="idle", type="int",\
            help="automaticaly close after IDLE time", metavar="IDLE")
        parser.add_option("-d", "--decrypt", dest="decrypt",\
            help="decrypt FOLDER", metavar="FOLDER")
        parser.add_option("-p", "--change-password", dest="change_password",\
            help="change the password of FOLDER", metavar="FOLDER")
        parser.add_option("-l", "--clean", action="store_true", dest="clean",\
            help="Clean directories list")
        parser.add_option("-s", "--stdin", action="store_true", dest="stdin",\
            default=False, help="Get input from stdin")
    
        (self.options, self.args) = parser.parse_args()

        #parser.error("only use one option at time")
            
        if self.options.idle is not None and self.options._open is None:
            parser.error("--idle option can only be used with --open option")
            
        elif self.options.crypt is not None:
            self.crypt()
            
        elif self.options.close is not None:
            self.close()
            
        elif self.options._open is not None:
            self._open()
            
        elif self.options.decrypt is not None:
            self.decrypt()
            
        elif self.options.change_password is not None:
            self.change_password()
            
        elif self.options.clean is not None:
            self.clean()
            
        else:
            self.folder_list()

    def exit(self):
        self.data.save()
        sys.exit()
    
    def getpass(self, text=None):
        if text is None:
            text = _("Password:")
        if self.options.stdin:
            return raw_input()
        try:
            return getpass.getpass(text)
        except:
            print _("Error: invalid argument.")
            print _("Try using --stdin option.")
            sys.exit(2)

    def clean(self):
        self.folders.clean()
        self.exit()

    def crypt(self):
        try:
            folder = conceal.Folder(self.options.crypt)
        except conceal.NotDir:
            print _("%s is not a folder.") % self.options.crypt
            sys.exit(2)
            
        password = self.getpass()
        
        try:
            conceal.Manage(folder).crypt(password)
        except conceal.AlreadyEncrypted:
            print _("%s is already an encrypted folder.") % folder.path
            sys.exit(2)
        
        self.folders.add(folder)
        self.exit()

    def change_password(self):
        try:
            folder = self.folders.get(self.options.change_password)
        except conceal.NoEncrypted:
            print _("%s is not an encrypted folder.") %\
                self.options.change_password
            sys.exit(2)
        
        current = self.getpass(_("Enter current folder password:"))
        new = self.getpass(_("Enter new folder password:"))
        confirmation = self.getpass(_("Retype new folder password:"))
        
        if not new == confirmation:
            print _("Sorry, passwords do not match.")
            sys.exit(2)
        
        try:
            conceal.Manage(folder).change_password(current, new)
        except conceal.BadPassword:
            print _("Wrong password.")
            print _("Password unchanged.")
            sys.exit(2)
            

    def close(self):
        try:
            folder = self.folders.get(self.options.close)
        except conceal.NoEncrypted:
            print _("%s is not an encrypted folder.") % self.options.close
            sys.exit(2)
        
        try:
            folder = conceal.Manage(folder).unmount()
        except conceal.NotOpened:
            print _("Directory %s is not opened.") % folder.path
            sys.exit(2)
        
        self.folders.update(folder)
        self.exit()

    def _open(self):
        try:
            folder = self.folders.get(self.options._open)
        except conceal.NoEncrypted:
            exit(_("%s is not an encrypted folder.") % self.options._open)
        password = self.getpass()
        
        try:
            folder = conceal.Manage(folder).mount(password, self.options.idle)
        except conceal.AlreadyOpened:
            print _("%s is already opened.") % folder.path
            sys.exit(2)
        
        except conceal.BadPassword:
            print _("Wrong password.")
            sys.exit(2)

        self.folders.update(folder)
        self.exit()

    def decrypt(self):
        try:
            folder = self.folders.get(self.options.decrypt)
        except conceal.NoEncrypted:
            print _("%s is not an encrypted folder.") % self.options.decrypt
            sys.exit(2)
        password = self.getpass()
        try:
            conceal.Manage(folder).decrypt(password)
        except conceal.BadPassword:
            print _("Wrong password.")
            sys.exit(2)
        self.folders.rem(folder)
        self.exit()

    def folder_list(self):
        if len(self.folders.li) > 0:
            print "%s	%s" % (_("Open"), _("Path"))

            for f in self.folders.li:
                if f.opened:
                    o = _("Yes")
                else:
                    o = _("No")
                
                print "%s	%s" % (o, f.path)
        else:
            print _("There is no encrypted folder.")
        self.exit()

if __name__ == '__main__':
    Main()
